/*
 * Copyright (c) 2013.
 * 游戏服务器核心代码编写人陈磊拥有使用权
 * 联系方式：E-mail:13638363871@163.com ;qq:502959937
 * 个人博客主页：http://my.oschina.net/chenleijava
 */

package com.dc.gameserver.serverCore.service.cardModule;

import com.dc.gameserver.baseConfig.Config;
import com.dc.gameserver.exceptions.logicException;
import com.dc.gameserver.hardCode.PkStatus;
import com.dc.gameserver.hardCode.playerGameStatus;
import com.dc.gameserver.proto.gameserverprotoVo.*;
import com.dc.gameserver.serverCore.service.battle.coreBattleLogic.ISameLogic;
import com.dc.gameserver.serverCore.service.battle.coreBattleLogic.ISingle;
import com.dc.gameserver.serverCore.service.battle.coreBattleLogic.Idifferent;
import com.dc.gameserver.serverCore.service.character.GameCharacter;
import com.dc.gameserver.serverCore.service.character.Monster;
import com.dc.gameserver.serverCore.service.character.PlayerInstance;
import com.dc.gameserver.serverCore.service.managerService.ThreadPoolManager;
import io.netty.buffer.ByteBuf;
import javolution.util.FastMap;
import javolution.util.FastTable;
import org.slf4j.Logger;

import java.util.List;
import java.util.concurrent.RunnableScheduledFuture;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author : 石头哥哥
 * Date: 13-10-26</br>
 * Time: 上午10:14</br>
 * Package: Server.ServerCore.Service.LicensingProcess</br>
 * 注解：  匹配成功的游戏对象对应一个CardBoxManager对象</br>
 * 游戏盒子对象管理类 以及游戏对象,所有玩家进入pk状态之后创建CardBoxManager对象</br>
 * 处于PK状态中的任何一个玩家退出PK状态的时候，该对象将会被销毁；</br>
 *
 * 当一个玩家离开PK状态(1.离线；2.从PK状态切换为非PK状态)的时候，cardBoxManager将会被销毁</br>
 * 每一回合结束之后：1.释放当前回合资源；2.判定当前回合是否结束；
 *
 * 关于对象持用该对象的实例状态，销毁时机 还有待考虑！！！！
 */
public class CardBoxManager {


    private static final Logger LOGGER= org.slf4j.LoggerFactory.getLogger(CardBoxManager.class);

    /**record CardBox id**/
    public static final AtomicInteger cardBoxAtomicInteger=new AtomicInteger(0);
    /**CardBox列表*/
    public static FastTable<CardBox> cardBoxes=new FastTable<CardBox>().shared();

    public static FastTable<CardBox> usedBoxes=new FastTable<CardBox>().shared();

    /**回合出牌计时任务map  only for PVE***/
    public static final FastMap<Integer, RunnableScheduledFuture<?>> roundTimeOutTaskMap=
            new FastMap<Integer, RunnableScheduledFuture<?>>().atomic();

    /**
     * 构造函数
     */
    public CardBoxManager(){}

    /**
     * 纸牌详细信息
     * 同步纸牌 p1--->p2
     * @param p1
     * @param p2
     * 如果p1为玩家，那么
     */
    public static void synCardList(GameCharacter p1,GameCharacter p2){
        synCardResponse.Builder response=synCardResponse.newBuilder();
        FastTable<Card> PlayerCardList=p1.getOutCardsList();
        for (com.dc.gameserver.serverCore.service.cardModule.Card card:PlayerCardList){
            netCardVO.Builder netCardBuilder=netCardVO.newBuilder();
            netCardBuilder.setCardNum(card.getType());//编号
            netCardBuilder.setCardCount(card.getCount());//点数
            response.addNetCardVO(netCardBuilder);
        }
        response.setPlayerID(p1.getID());
        p2.DirectSend(CardBox.wrappedBufferShort(synCardResponse.msgID.ID_VALUE,response.build()));
    }

    /**
     *
     * 排序玩家优先级 :1,2,3,4；较小的优先级大
     * @param p1
     * @param p2
     * @return  PlayerInstance[0] 优先级较大玩家  ; PlayerInstance[1]:优先级较小的玩家
     */
    public static  GameCharacter[] orderPriorityPlayer(GameCharacter p1, GameCharacter p2){
        GameCharacter[] orderList=new GameCharacter[2];
        int t1=p1.getCardType().getType();
        int t2=p2.getCardType().getType();
        if (t1<t2){
            orderList[0]=p1;
            orderList[1]=p2;
        }else {
            orderList[0]=p2;
            orderList[1]=p1;
        }
        return orderList;
    }


    /**
     * 初始化  CardBox容器
     */
    public static void IntiCardBoxList(){
        for (int i=0;i!=  Config.DEFAULT_VALUE.GAME_VALUE.cardBoxNum;++i){
            CardBox box=new CardBox(cardBoxAtomicInteger.getAndIncrement());
            cardBoxes.addLast(box);
        }
    }

    /**
     * 创建新的cardBox对象
     * @return
     */
    public static CardBox getNewCardBox(){
        CardBox box=cardBoxes.pollFirst();  //get first
        if (box==null){
            box=new CardBox(cardBoxAtomicInteger.getAndIncrement());
            usedBoxes.addLast(box);
            return box;
        }
        usedBoxes.addLast(box);
        return box;
    }



    /**
     *  PK结束，清理PK资源,清理回合资源
     *  1.card 对象
     *  2.CardBox对象
     *  3.回合之前数据变量状态
     */
    public static void clearPkResourceWithRoundOver(int CardBoxID){
        LOGGER.debug("当前执行的线程:"+Thread.currentThread().getName());
        CardBox cardBox=getCardBoxByID(CardBoxID);
        FastTable<GameCharacter> playerInstances=cardBox.getInGamePlayerList();
        for (GameCharacter player:playerInstances){
            player.clearPkResourceWithRoundOver(cardBox);
        }
        //清理cardBox持有资源
        cardBox.getCheckOutCardPlayerList().clear();
        cardBox.getBattle().clearResource();
        cardBox.setBattle(null);
        cardBox.getRoundCount().set(0);
        cardBox.getInGamePlayerList().clear();
        //清除计时任务
        CardBoxManager.removeRoundTimeOutTask(CardBoxID);
        //回收cardBox
        cardBoxes.addLast(cardBox);
        usedBoxes.remove(cardBox);
    }


    /**
     * 玩家离线 清除cardBox资源
     * @param CardBoxID
     */
    public static void  clearCardBoxAndCardIfPlayerOffile(int CardBoxID){
        CardBox cardBox=getCardBoxByID(CardBoxID);
        FastTable<GameCharacter> playerInstances=cardBox.getInGamePlayerList();
        for (GameCharacter gameCharacter:playerInstances){
            gameCharacter.clearAllResourceOutOfPK(cardBox);
        }
        //清理cardBox持有资源
        cardBox.getCheckOutCardPlayerList().clear();
        cardBox.getBattle().clearResource();
        cardBox.setBattle(null);
        cardBox.getRoundCount().set(0);
        cardBox.getInGamePlayerList().clear();
        //清除计时任务
        CardBoxManager.removeRoundTimeOutTask(CardBoxID);
        //回收cardBox
        cardBoxes.addLast(cardBox);
        usedBoxes.remove(cardBox);
    }

    /**
     * 匹配    CardBox
     * 在controller：BattleReadyController  和 reserveBattleReadyController 中回调
     * @param player           接受挑战 玩家
     * @param givePkPlayer       发起挑战 玩家
     */
    public static void matchCardBox(PlayerInstance player, PlayerInstance givePkPlayer){

        CardBox cardBox=CardBoxManager.getNewCardBox();
        int cardBoxID=cardBox.getCardBoxID();
        player.setCardBoxID(cardBoxID);
        givePkPlayer.setCardBoxID(cardBoxID);
        cardBox.getInGamePlayerList().addAll(player,givePkPlayer);

        /**
         * 添加玩家到check列表，完成出牌检查做准备，每一回合结束后将会重置
         * 详见函数{@link com.dc.gameserver.serverCore.service.cardModule.CardBoxManager#resetRoundResource()}
         */
        cardBox.getCheckOutCardPlayerList().addAll(givePkPlayer,player);

        /**set player in PK status***/
        givePkPlayer.setPkStatus(PkStatus.YES_PK);
        player.setPkStatus(PkStatus.YES_PK);

        /**初始化游戏数据牌*/
        cardBox.ClearAndIntiCardBox(player, givePkPlayer);

        //syn player information
        synInformation(player,givePkPlayer);
        synInformation(givePkPlayer,player);


        /**推送指定玩家的牌数据列表*/
        sendList(player);
        sendList(givePkPlayer);

        /**添加回合超时计时任务**/
        registerRoundOutCardTimeOutTaskAndExecutorForPVP(new FastTable<GameCharacter>().addAll(player, givePkPlayer));


        /***
         * {@link com.dc.gameserver.serverCore.controller.handleController.pvpCoreController.battleReadyController#DispatchMessageLit(com.google.protobuf.MessageLite, com.dc.gameserver.serverCore.model.player.PlayerInstance)}
         * {@link CardBoxManager#MatchCardBox(com.dc.gameserver.serverCore.model.player.PlayerInstance, com.dc.gameserver.serverCore.model.player.PlayerInstance)}
         * **/
        int round=cardBox.RoundCount();
        CardBoxManager.notifyOutCards(player,true,round);
        CardBoxManager.notifyOutCards(givePkPlayer,true,round);

    }

    /**
     * 在回合开始就取消该计时任务
     * PVP注册回合出牌计时回合超时任务并执行
     */
    public static void registerRoundOutCardTimeOutTaskAndExecutorForPVP(final FastTable<GameCharacter> playerInstances){
        final Runnable task = new Runnable(){
            @Override
            public void run() {
                if(playerInstances.size()<=0){
                    throw new logicException("回合计时器逻辑异常，playerInstances 不为空！！！");
                }
                /**临时出牌列表（判定玩家是否都出牌到预出牌临时区域）*/
                CardBox cardBox=CardBoxManager.getCardBoxByID(playerInstances.getFirst().getCardBoxID());
                if (cardBox!=null){
                    FastTable <GameCharacter > checkList=cardBox.getCheckOutCardPlayerList();
                    int size =playerInstances.size();
                    /**单个玩家可能超时***/
                    if (size==1){
                        GameCharacter player=playerInstances.poll();
                        if (!player.isActionOutCard()) {
                            notifyRoundTimeOut((PlayerInstance)player,cardBox);   // 通知超时，且弃牌
                            player.setActionOutCard(true);
                            checkList.remove(player);
                            //另一个玩家为眩晕状态，检查眩晕
                            PlayerInstance otherPlayer= (PlayerInstance) cardBox.getOtherPlayer(player);
                            int DizinessTimes=otherPlayer.getDizzinessTimes();
                            if (DizinessTimes!=0){
                                otherPlayer.setDizzinessTimes(--DizinessTimes);
                                if (otherPlayer.getDizzinessTimes()<=0){
                                    otherPlayer.setDizzinessTimes(0);
                                    dizzniessResponse.Builder builder=dizzniessResponse.newBuilder();
                                    builder.setPlayerID(otherPlayer.getID());
                                    builder.setResult(playerGameStatus.undizziness.getStatus());      //同步，pp解除眩晕
                                    cardBox.submitMessageToEveryOne(CardBox.wrappedBufferShort(dizzniessResponse.msgID.ID_VALUE, builder.build()));
                                }
                            }
                            //over  ,notify  out card
                            sysInformationAndCards((PlayerInstance)player, cardBox);
                            sysInformationAndCards(otherPlayer, cardBox);
                            //注册回合超时
                            registerRoundOutCardTimeOutTaskAndExecutorForPVP(new FastTable<GameCharacter>().addAll(player, otherPlayer));
                        }
                        playerInstances.clear();
                        return;
                    }
                    //两个人都可以出牌
                    if (size==2){
                        GameCharacter player1=playerInstances.getFirst();
                        GameCharacter player2=playerInstances.getLast();
                        /**
                         * 都超时
                         */
                        if (!player1.isActionOutCard()&&!player2.isActionOutCard()) {
                            for (GameCharacter player:playerInstances){
                                syNotifyRoundTimeOutResponse.Builder builder=syNotifyRoundTimeOutResponse.newBuilder();
                                builder.setPlayerID(player.getID());
                                player.DirectSend(CardBox.wrappedBufferShort(syNotifyRoundTimeOutResponse.msgID.ID_VALUE,builder.build()));
                                player.setActionOutCard(true);
                                sysInformationAndCards((PlayerInstance)player,cardBox);
                            }
                            playerInstances.clear();
                            //注册回合超时
                            registerRoundOutCardTimeOutTaskAndExecutorForPVP(new FastTable<GameCharacter>().addAll(player1, player2));
                            return;
                        }

                        //单个玩家超时 ，那么另一个玩家必然是出牌了，或则放弃了出牌
                        if (!player1.isActionOutCard()&&player2.isActionOutCard()){
                            notifyRoundTimeOut((PlayerInstance)player1,cardBox);   // 通知超时，且弃牌
                            player1.setActionOutCard(true);
                            checkList.remove(player1);
                            if (checkList.size()==0){
                                FastTable<GameCharacter> outCardPlayerList=cardBox.getTempOutCardPlayerList();
                                int outCard=outCardPlayerList.size();
                                if (outCard==0){
                                    cardBox.flushBloodAndMagic();
                                    cardBox.resetRoundResource();
                                    return;
                                }
                                //按照放弃出牌处理，player2出牌有效
                                if (outCard==1){
                                    synCardList(player2, player1);
                                    ISingle.SINGLES[player2.getCardType().getType()].SingleLogicHandle(player2,player1);
                                }
                            }
                            playerInstances.clear();
                            return;
                        }
                        if (!player2.isActionOutCard()&&player1.isActionOutCard()){
                            notifyRoundTimeOut((PlayerInstance)player2,cardBox);   // 通知超时，且弃牌
                            player2.setActionOutCard(true);
                            checkList.remove(player2);
                            if (checkList.size()==0){
                                FastTable<GameCharacter> outCardPlayerList=cardBox.getTempOutCardPlayerList();
                                int outCard=outCardPlayerList.size();
                                if (outCard==0){
                                    cardBox.flushBloodAndMagic();
                                    cardBox.resetRoundResource();
                                    return;
                                }
                                //按照放弃出牌处理，player1出牌有效
                                if (outCard==1){
                                   synCardList(player1, player2);
                                    ISingle.SINGLES[player1.getCardType().getType()].SingleLogicHandle(player1,player2);
                                }
                            }
                            playerInstances.clear();
                        }
                    }
                }  else {
                    throw  new logicException("回合计时器逻辑异常，CardBox  不为空");
                }
            }
        };
        //注册回合之间的间隔时间2秒
        ThreadPoolManager.getInstance().scheduleRoudTimeOut(task,Config.DEFAULT_VALUE.GAME_VALUE.roundOutCardIntervalTimeOut);
    }





    /**
     * 玩家超时
     * PVE注册回合出牌计时超时任务并执行
     * @param gameCharacter    PlayerInstance
     */
    public static void registerRoundOutCardTimeOutTaskAndExecutorForPVE(final GameCharacter gameCharacter){
        final Runnable task=new Runnable() {
            @Override
            public void run() {
                if (gameCharacter instanceof Monster){
                    throw  new logicException("player  must be a PlayerInstance object");
                }
                final CardBox cardBox=CardBoxManager.getCardBoxByID(gameCharacter.getCardBoxID());
                CardBoxManager.removeRoundTimeOutTask(gameCharacter.getCardBoxID());  //移除map
                int Dizziness=gameCharacter.getDizzinessTimes();
                if (Dizziness!=0){
                    Dizziness=Dizziness-1;
                    gameCharacter.setDizzinessTimes(Dizziness);
                    if (Dizziness==0){
                        //notify  unDizzniess
                        dizzniessResponse.Builder builder= dizzniessResponse.newBuilder();
                        builder.setResult(playerGameStatus.undizziness.getStatus());
                        builder.setPlayerID(gameCharacter.getID());
                        cardBox.submitMessageToEveryOne(CardBox.wrappedBufferShort(dizzniessResponse.msgID.ID_VALUE, builder.build()));
                    }
                }
                //time  out,the monster will be auto attack the player util to die!
                Monster monster=(Monster) cardBox.getOtherPlayer(gameCharacter);
                FastTable<Card> monsterCard=monster.monsterOutCards();
                if (monsterCard!=null){
                    for (Card c:monsterCard){
                        monster.addOutCard(c);
                    }
                    monsterCard.clear();
                    monsterCard=null;   //purge list
                    //syn card   monsterCard--->player
                    CardBoxManager.synCardList(monster, gameCharacter);

                    cardBox.getTempOutCardPlayerList().add(monster);
                    //logic single out card; monster  out card
                   if (Config.DEFAULT_VALUE.SERVER_VALUE.useMultleThread){
                       final Runnable runnable=new Runnable() {
                           @Override
                           public void run() {
                               coreLogic(cardBox);
                           }
                       } ;
                       ThreadPoolManager.getInstance().executeCalculate(runnable);
                   }else {
                       coreLogic(cardBox);
                   }
                } else {
                    //monster give out card;
                    cardBox.flushBloodAndMagic();
                    cardBox.resetRoundResource();
                    cardBox.getTempOutCardPlayerList().clear();
                }
            }
        } ;
         //注册出牌超时 ，如果玩家出牌之后，那么就会取消超时
        RunnableScheduledFuture<?> scheduledFuture=
                (RunnableScheduledFuture<?>)ThreadPoolManager.getInstance().
                        scheduleRoudTimeOut(task, Config.DEFAULT_VALUE.GAME_VALUE.roundOutCardIntervalTimeOut);
        LOGGER.debug("注册回合任务：" + scheduledFuture.toString());
        LOGGER.debug("注册超时时间");
        LOGGER.debug("当前计时map中的个数为："+roundTimeOutTaskMap.size());
        roundTimeOutTaskMap.put(gameCharacter.getCardBoxID(),scheduledFuture);
    }


    /**
     *  PVE中
     *  移除回合出牌计时任务 ，不管是主动出牌  还是放弃出牌，那么map中的
     *  键值对总是会被移除，且在注册的时候，map为中的个数为0;
     */
    public static void removeRoundTimeOutTask(int cardBoxID){
        //如果map中存在 注册的计时任务
        if (roundTimeOutTaskMap.containsKey(cardBoxID)){
            RunnableScheduledFuture<?> task=roundTimeOutTaskMap.get(cardBoxID);
            ThreadPoolManager.getInstance().removeRoudTimeOutTimerTask(task);
            roundTimeOutTaskMap.remove(cardBoxID);// always remove  map
        }
    }


    /**
     * 通知player 回合超时
     * @param player   超时玩家
     */
    private static void notifyRoundTimeOut(PlayerInstance player ,CardBox cardBox){
        syNotifyRoundTimeOutResponse.Builder builder=syNotifyRoundTimeOutResponse.newBuilder();
        builder.setPlayerID(player.getID());
        FastTable<GameCharacter> playerInstanceFastTable= cardBox.getInGamePlayerList();
        ByteBuf byteBuf= CardBox.wrappedBufferShort(syNotifyRoundTimeOutResponse.msgID.ID_VALUE, builder.build());
        for (GameCharacter playerInstance:playerInstanceFastTable){
            playerInstance.DirectSend(byteBuf.copy());
        }
        byteBuf.release();
        byteBuf=null;
    }

    /**
     * 同步发牌 和玩家的气血 蓝值
     * @param player
     * @param cardBox
     */
    private static void sysInformationAndCards(PlayerInstance player,CardBox cardBox){
        player.clearRoundResource();  //清空player资源  for next

        cardBox.getCheckOutCardPlayerList().add(player);//ready for next
        //new card
        Card[] cards=cardBox.getOutCardsAndRecoveryMagic(player);

        synResetRoundCardResponse.Builder builder=synResetRoundCardResponse.newBuilder();
        if (cards!=null){
            //new  card from system
            for (Card card:cards){
                netCardVO.Builder netCardBuilder=netCardVO.newBuilder();
                netCardBuilder.setCardNum(card.getType());//编号
                netCardBuilder.setCardCount(card.getCount());//点数
                builder.addNewList(netCardBuilder.build()) ;
            }
        }
        //all card
        FastTable<Card> PlayerCardList=player.getCardlib();
        for (com.dc.gameserver.serverCore.service.cardModule.Card card:PlayerCardList){
            netCardVO.Builder netCardBuilder=netCardVO.newBuilder();
            netCardBuilder.setCardNum(card.getType());//编号
            netCardBuilder.setCardCount(card.getCount());//点数
            builder.addAllList(netCardBuilder.build());
        }
        builder.setPlayerID(player.getID());
        player.DirectSend(CardBox.wrappedBufferShort(synResetRoundCardResponse.msgID.ID_VALUE, builder.build()));


        /***刷新玩家的法术盾*/
        synResetRoundPlayerInfoResponse.Builder playerInfoVO=synResetRoundPlayerInfoResponse.newBuilder();
        playerInfoVO.setPlayerID(player.getID());
        playerInfoVO.setMagic(player.getCurrentMagic());
        playerInfoVO.setShield(player.getCurrentShield());
        ByteBuf infomation=CardBox.wrappedBufferShort(synResetRoundPlayerInfoResponse.msgID.ID_VALUE, playerInfoVO.build());
        for (GameCharacter pp:cardBox.getInGamePlayerList()){
            pp.DirectSend(infomation.copy());
        }
        infomation.release();
        infomation=null;
    }

    /**
     *  同步信息
     * @param p1  信息源
     * @param p2   接收信息源
     */
    public static void synInformation(PlayerInstance p1,PlayerInstance p2){
        synPlayerInformationResponse.Builder builder=synPlayerInformationResponse.newBuilder();
        builder.setPlayerID(p1.getID());
        builder.setMaxShield(p1.getMaxShield());
        builder.setCurrentShield(p1.getCurrentShield());
        builder.setMaxMagic(p1.getMaxMagic());
        builder.setCurrentMagic(p1.getCurrentMagic());
        builder.setCardNum(p1.getCardlib().size());
        p2.DirectSend(CardBox.wrappedBufferShort(synPlayerInformationResponse.msgID.ID_VALUE,builder.build()));
    }


    /**
     * 推送指定玩家的牌数据列表
     * @param player
     */
    private  static  void sendList(PlayerInstance player){
        BattleReadyResponse.Builder builder= BattleReadyResponse.newBuilder();
        FastTable<Card> PlayerCardList=player.getCardlib();
        for (com.dc.gameserver.serverCore.service.cardModule.Card card:PlayerCardList){
            //构建网络传输纸牌vo
            netCardVO.Builder netCardBuilder=netCardVO.newBuilder();
            netCardBuilder.setCardNum(card.getType());//编号
            netCardBuilder.setCardCount(card.getCount());//点数
            builder.addCardList(netCardBuilder.build());
        }
        // 请求挑战的ip
        builder.setPlayerID(player.getID());

        player.DirectSend(CardBox.wrappedBufferShort(BattleReadyResponse.msgID.ID_VALUE, builder.build()));
    }


    /**
     * 获取指定的cardBox
     * @param cardBoxID
     * @return      maybe Return  null
     */
    public static CardBox getCardBoxByID(int cardBoxID){
        for (CardBox  cardBox:usedBoxes){
            if (cardBox.getCardBoxID()==cardBoxID){
                return cardBox;
            }
        }
       return null;
    }




    /**
     * 根据规则
     * 计算gameCharacter 使用防御的 法力值消耗 ，  法力盾增加
     * @param gameCharacters
     *
     * 消耗的法力值：牌的张数*  FangreduceMagic
     * 增加的法力盾：牌的张数*  Fangrecoverysheild
     *
     */
    public static void DeffenceCompute(GameCharacter...gameCharacters){
        for (GameCharacter gameCharacter:gameCharacters){
            //回血  扣蓝（发力盾）
            List<Card> playerOutCardsList=gameCharacter.getOutCardsList();
            int cardNum=playerOutCardsList.size();

            int  shield=cardNum*gameCharacter.getFangrecoverysheild();//法术盾
            int  magic=cardNum*gameCharacter.getFangreduceMagic();//法力值

            gameCharacter.setCurrentMagic(gameCharacter.getCurrentMagic()-magic);
            int tempShield=shield+gameCharacter.getCurrentShield();
            int maxShield= gameCharacter.getMaxShield();
            if (tempShield>maxShield ){
                gameCharacter.setCurrentShield(maxShield);
            }else {
                gameCharacter.setCurrentShield(tempShield);
            }
        }
    }




    /**
     * 通知player 出牌
     * notify player out cards to temp  area,this is a loop point
     * @param gameCharacter      notify object
     * @param canOut   true or false
     */
    public  static void  notifyOutCards(GameCharacter gameCharacter,boolean canOut,int roundCount){
        outCardResponse.Builder builder= outCardResponse.newBuilder();
        builder.setCanOutCard(canOut);   //if true  can out card  ,or it can not out card
        builder.setRound(roundCount);//  回合数
        gameCharacter.DirectSend(CardBox.wrappedBufferShort(outCardResponse.msgID.ID_VALUE, builder.build()));
    }



    /**
     * 当前逻辑处理是用线程池 #+逻辑处理线程+# 在处理 ，处理的逻辑包含两个部分：1.数据分发，基本的controller；2.核心计算逻辑（包含数据库的操作）
     *
     * 核心逻辑计算包含了处理数据库部分，后期考虑是否使用线程池来处理这部分的逻辑
     * 核心逻辑计算
     * @param cardBox
     */
    public static  void  coreLogic(CardBox cardBox){
        FastTable<GameCharacter> outCardPlayerList=cardBox.getTempOutCardPlayerList();
        int size=outCardPlayerList.size();
        System.out.println("出牌的玩家数量-->>:"+size);
        if (size==0){
            cardBox.flushBloodAndMagic();
            cardBox.resetRoundResource();
            outCardPlayerList.clear();
            return;
        }
        /**
         * only one player out card
         * 1. if monster dizzniess, only player;
         * 2. if monster not dizzniess , player give out card , only monster
         * */
        if (size==1){
            GameCharacter p1=null,p2=null;
            p1=outCardPlayerList.pollLast(); //p1为出牌玩家
            p2=cardBox.getOtherPlayer(p1);  //p2 没有出牌对象
            outCardPlayerList.clear();
            if (p1!=null&&p2!=null){
                //syn p1 card to p2, if p1 is a player ,not syn card for monster
                //出牌玩家为monster对象 ,p2 is player
                if (p1 instanceof Monster&&p2 instanceof PlayerInstance){
                    CardBoxManager.synCardList(p1,p2);
                }
                if (p1 instanceof PlayerInstance&&p2 instanceof PlayerInstance){
                    CardBoxManager.synCardList(p1,p2);
                }
                System.out.println("size 1 出牌同步完毕-->>:");
                ISingle.SINGLES[p1.getCardType().getType()].SingleLogicHandle(p1,p2);
                p1.setCardType(null);
                p2.setCardType(null);
            } else {
                throw  new logicException("p1,p2 must not be null ... ...");
            }
            return;
        }

        /***two player out card*/
        if (size==2){
            int i,j=0;  //cardType num
            GameCharacter p1=null,p2=null;
            p1=outCardPlayerList.get(0);
            p2=outCardPlayerList.get(1);
            outCardPlayerList.clear();
            if (p1!=null&&p2!=null){
                i=p1.getCardType().getType();
                j=p2.getCardType().getType();
                //syn monster card to player
                if (p1 instanceof PlayerInstance&& p2 instanceof Monster){
                    //p2  monster ,p1 player
                    CardBoxManager.synCardList(p2,p1);
                } else if (p1 instanceof Monster&& p2 instanceof PlayerInstance){
                    //p1  monster ,p2 player
                    CardBoxManager.synCardList(p1, p2);
                }else {
                    // pvp
                    CardBoxManager.synCardList(p1,p2);
                    CardBoxManager.synCardList(p2,p1);
                }

                System.out.println("size  2 出牌同步完毕-->>:");
                if (i==j){
                    System.out.println("出相同牌-->>:");
                    ISameLogic.LOGICS[i].logicHandle(p1,p2);
                    p1.setCardType(null);
                    p2.setCardType(null);
                } else {
                    System.out.println("出不%%相同牌-->>:");
                    //out different cards .12,13,14,23,24,34
                    GameCharacter[]playerInstances= CardBoxManager.orderPriorityPlayer(p1, p2);//order player
                    int index=Integer.parseInt(playerInstances[0].getCardType().getType()+""+playerInstances[1].getCardType().getType());
                    System.out.println("出不%%相同牌类型编号 12,13,14,23,24,34-->>:"+index);
                    Idifferent.IDIFFERENTS[index].differentLogicHandle(playerInstances[0], playerInstances[1]);
                    playerInstances=null;
                    p1.setCardType(null);
                    p2.setCardType(null);
                }
            }
        }
    }

}
